package hw03;

import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class Schema {
	
	private Set<RelationalSignature> relationalSignatures;
	private Set<FunctionalDependency> functionalDependencies;
	private Set<MultivaluedDependency> multiValuedDependencies;

	public Schema() {
		relationalSignatures = new TreeSet<RelationalSignature>();
		functionalDependencies = new TreeSet<FunctionalDependency>();
		multiValuedDependencies = new TreeSet<MultivaluedDependency>();
	}

	public Set<RelationalSignature> getRelationalSignatures() {
		return relationalSignatures;
	}
	
	public Set<FunctionalDependency> getFunctionalDependencies() {
		return functionalDependencies;
	}
	
	public Set<MultivaluedDependency> getMultiValuedDependencies() {
		return multiValuedDependencies;
	}
	
	public void to3NF() {
		Set<RelationalSignature> oldSignatures = getRelationalSignatures();
		relationalSignatures = new TreeSet<RelationalSignature>();
		for(RelationalSignature R : oldSignatures) {
			Set<FunctionalDependency> F = Utils.projectDependencies(R, R, getFunctionalDependencies());
			relationalSignatures.addAll(Utils.decomposeInto3NF(R, F));
		}
	}

	public void toBCNF() {
		Set<RelationalSignature> oldSignatures = getRelationalSignatures();
		relationalSignatures = new TreeSet<RelationalSignature>();
		for(RelationalSignature R0 : oldSignatures) {
			Set<FunctionalDependency> S = Utils.projectDependencies(R0, R0, getFunctionalDependencies());
			relationalSignatures.addAll(Utils.decomposeIntoBCNF(R0, S));
		}
	}
	
	public void toOrig() {
		relationalSignatures = Utils.join(getRelationalSignatures());
	}

	public void to4Nf() {
		Schema fnf = new Schema();
		Set<MultivaluedDependency> S0 = new TreeSet<MultivaluedDependency>(getMultiValuedDependencies());
		for(FunctionalDependency FD : getFunctionalDependencies()) {
			S0.add(new MultivaluedDependency(FD));
		}
		for(RelationalSignature R0 : getRelationalSignatures()) {
			fnf.relationalSignatures.addAll(Utils.decomposeInto4NF(R0, S0));
		}
		fnf.multiValuedDependencies.addAll(getMultiValuedDependencies());
		fnf.functionalDependencies.addAll(getFunctionalDependencies());
	}

	@Override
	public String toString() {
		String toString = "";
		Iterator<RelationalSignature> rsIter = getRelationalSignatures().iterator();
		while(rsIter.hasNext()) {
			toString += rsIter.next() + "\n";
		}
		Iterator<FunctionalDependency> fdIter = getFunctionalDependencies().iterator();
		while(fdIter.hasNext()) {
			toString += fdIter.next() + "\n";
		}
		Iterator<MultivaluedDependency> mvdIter = getMultiValuedDependencies().iterator();
		while(mvdIter.hasNext()) {
			toString += mvdIter.next() + "\n";
		}
		return toString;
	}
	
}
